import 'dart:async';
import 'package:flutter_reactive_ble/flutter_reactive_ble.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:sleep/model/blue/blue_model.dart';
import 'package:sleep/provider/db_provider.dart';

class BlueScanerNotifier extends StateNotifier<List<BlueModel>> {
  final FlutterReactiveBle ble;
  BlueScanerNotifier(this.ble) : super([]) {
    startScan([]);
  }

  StreamSubscription? _subscription;

  _stream(DiscoveredDevice device) {
    if (device.name.isEmpty) return;

    BlueModel model = BlueModel.toBlueModel(device);
    bool has = state.any(((element) => element.deviceId == model.deviceId));
    if (!has) {
      state = [...state, model];
    }
  }

  startScan(List<Uuid> serviceIds) {
    _subscription?.cancel();
    _subscription =
        ble.scanForDevices(withServices: serviceIds).listen(_stream);
  }

  stopScan() {
    _subscription?.cancel();
    _subscription = null;
  }

  @override
  void dispose() {
    stopScan();
    super.dispose();
  }
}

final scanProvider =
    StateNotifierProvider.autoDispose<BlueScanerNotifier, List<BlueModel>>(
        (ref) {
  return BlueScanerNotifier(FlutterReactiveBle());
});

final scanResultProvider = Provider.autoDispose<List<BlueModel>>((ref) {
  final scanBlue = ref.watch(scanProvider);
  final dbBlue = ref.watch(dbProvider);
  final sleepBlue = dbBlue.getBlueModel(kSleepBlue);
  final plueBlue = dbBlue.getBlueModel(kPlueBlue);
  final faigueBlue = dbBlue.getBlueModel(kFaigueBlue);

  return scanBlue.where((element) {
    return sleepBlue?.deviceId != element.deviceId &&
        plueBlue?.deviceId != element.deviceId &&
        faigueBlue?.deviceId != element.deviceId;
  }).toList();
});
